﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using Sonic.Framework.Interfaces;
using Sonic.Framework.Enums;
using System.Xml;
using System.Text.RegularExpressions;

namespace Sonic.Framework.ProcessorToolDirectives.Default
{
    /// <summary>
    /// Filters out files from the processor tool file list based on a regular expression
    /// </summary>
    public class FileNameFilter : IPluginBase, IProcessorToolDirective
    {
        private const string _name = "FileNameFilter";
        public string Name
        {
            get { return _name; }
        }

        private Dictionary<string, string> _attributes;
        public Dictionary<string, string> Attributes
        {
            get
            {
                return _attributes;
            }
        }

        public FileNameFilter()
        {
            this._attributes = new Dictionary<string, string>();
        }

        public bool Execute(ISonicProcessor processor, ISiteDirectory siteDir, ref List<FileInfo> directoryFileInfos, XmlDocument argumentsXml)
        {
            // Get the regex pattern to exclude
            string pattern = GetDirectiveCallAttributeFromArgXml(argumentsXml, "pattern");
            if (pattern == null || pattern == "")
            {
                throw new ArgumentException("A FileNameFilter call must define a regular expression pattern to match against");
            }

            if (pattern == null || pattern == "") return true;

            // Useful for date stamp filtering
            bool deleteMatchingFiles = false;
            try
            {
                deleteMatchingFiles = bool.Parse(GetDirectiveCallAttributeFromArgXml(argumentsXml, "deleteMatchingFiles"));
            }
            catch
            {
                deleteMatchingFiles = false;
            }

            ExcludeFiles(ref directoryFileInfos, pattern, deleteMatchingFiles);

            return true;
        }


        private void ExcludeFiles(ref List<FileInfo> directoryFileInfos, string pattern, bool deleteMatchingFiles)
        {
            for(int i=0; i<directoryFileInfos.Count; i++)
            {
                FileInfo file = directoryFileInfos[i];

                if (Regex.Match(file.Name, pattern, RegexOptions.IgnoreCase).Success)
                {
                    if (deleteMatchingFiles)
                    {
                        file.Delete();
                    }

                    directoryFileInfos.RemoveAt(i);
                    i--;
                }
            }
        }
    }
}
